package com.project.util;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect //标识该类为切面类
public class CutUtil {

    //第一个星号表示方法任意返回类型
    //com.project.service.. 表示匹配指定包及子包中的类
    //*.* 匹配任何类的任何方法
    //(..) 匹配方法任何参数
    //表示com.project.service包中所有类，在执行所有方法时，都会调用该方法
    @Before("execution(* com.project.service..*.*(..))")
    public void before(){
        System.out.println("before前置通知");
    }

    @After("execution(* com.project.service..*.*(..))")
    public void after(){
        System.out.println("after后通知");
    }

    @Around("execution(* com.project.service..*.*(..))")
    public Object  around(ProceedingJoinPoint point){
        System.out.println("环绕前");
        //得到目标对象
        Object target = point.getTarget();
        try {
            //执行目标方法，得到方法执行后的返回值
            Object returnObj = point.proceed();
            System.out.println("环绕后");
            return returnObj;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return null;
    }

    @AfterThrowing(value = "execution(* com.project.service..*.*(..))",
                throwing = "e")
    public void throwException(JoinPoint point,Exception e){
        //得到目标对象
        Object targetObj = point.getTarget();
        //得到执行目标方法名
        String methodName = point.getSignature().toString();

        System.out.println("执行"+targetObj.getClass().getSimpleName()+"的"+methodName
                +"方法，抛出"+e.getClass().getSimpleName()+"异常");
    }
}
